//
//  dh11.c
//  wireless_sensor
//
//  Created by fukai on 2018/11.
//  Copyright © 2018年 赛博智能车实验室. All rights reserved.
//

#include "dh11.h"
#include "stm32f10x.h"

DHT11MessageNode DHT11Message = 
{
	.temperature = 0,
	.humidity = 0,
};

//数据线输出
void DHT11DataPinOutput(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(DHT11_RCC,ENABLE);//使能GPIOA
	
	GPIO_InitStructure.GPIO_Pin = DHT11_Pin;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	//推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(DHT11_GPIO,&GPIO_InitStructure);
}

//数据线输入
void DHT11DataPinInput(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(DHT11_RCC,ENABLE);//使能GPIOA
	
	GPIO_InitStructure.GPIO_Pin = DHT11_Pin;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	//上拉输入
	//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(DHT11_GPIO,&GPIO_InitStructure);
}


//复位DHT11
void DHT11Reset(void)
{
	DHT11_DATA_OUT();
	DHT11_L();
	DELAY_MS(20);//拉低至少18ms
	DHT11_H();
	DELAY_US(30);//主机拉高20~40us
}

//等待DHT11响应
unsigned char DHT11Check(void)
{
	unsigned char retry = 0;
	
	DHT11_DATA_IN();
	while(DHT11_READ()&& (retry<100))//DHT11会拉低40~80us
	{
		retry++;
		DELAY_US(1);
	}
	if(retry>=100)	
	{
		return 1;
	}
	else 
	{
		retry = 0;
	}
	while((!DHT11_READ()) && (retry<100))//DHT11拉低后会再次拉高40~80us
	{
		retry++;
		DELAY_US(1);
	}
	if(retry>=100)	
	{
		return 1;
	}
	return 0;
}


//初始化DHT11的IO口 DQ 同时检测DHT11的存在
//返回1:不存在
//返回0:存在   
unsigned char DHT11Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(DHT11_RCC,ENABLE);//使能GPIOA
	
	GPIO_InitStructure.GPIO_Pin = DHT11_Pin;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	//推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(DHT11_GPIO,&GPIO_InitStructure);
	
	GPIO_SetBits(DHT11_GPIO,DHT11_Pin);
	
	DHT11Reset();	//复位DHT11
	return DHT11Check();
}

//从DH11读取一个位
//返回值：1/0
unsigned char DHT11ReadBit(void)
{
	unsigned char retry = 0;
	
	DHT11_DATA_IN();
	while(DHT11_READ()&& (retry<100))	//等待变为低电平
	{
		retry++;
		DELAY_US(1);
	}
	retry = 0;
	while((!DHT11_READ()) && (retry<100))	//等待变为高电平
	{
		retry++;
		DELAY_US(1);
	}
	DELAY_US(40);
	if(DHT11_READ())
	{
		return 1;
	}
	return 0;
}

//从DHT11读取一个字节
//返回值：读到的数据
unsigned char DHT11ReadByte(void)
{
	unsigned char count = 0;
	unsigned char dat = 0;
	for(count=0; count<8; count++)
	{
		dat <<= 1;
		dat |= DHT11ReadBit();
	}
	return dat;   
}

//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值：0,正常;1,读取失败
unsigned char DHT11ReadData(unsigned char *temp, unsigned char *humi)
{
	unsigned char buf[5];
	unsigned char count = 0;
	DHT11Reset();
	if(DHT11Check() == 0)
	{
		for(count=0; count<5; count++)
		{
			buf[count] = DHT11ReadByte();
		}
		if((buf[0]+buf[1]+buf[2]+buf[3]) == buf[4])
		{
			*humi = buf[0];
			*temp = buf[2];
		}
	}
	else
	{
		return 1;
	}
	return 0;
}



